#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "counter.h"
#include "mutex.h"


struct counter_t counter_create()
{
  struct counter_t result;
  result.error = 1;
  result.mutex_id = unsafe_mutex_create();
  if (result.mutex_id == -1) {
    return result;
  }
  result.shm_id = shmget(IPC_PRIVATE, sizeof(int), 0600);
  if (result.shm_id == -1) {
    mutex_destroy(result.mutex_id);
    return result;
  }
  void * r =  shmat(result.shm_id, 0, 0);
  if (r <= 0) 
  {
    mutex_destroy(result.mutex_id);
    shmctl(result.shm_id, IPC_RMID, 0);
    return result;
  }
  result.counter = (int *)r;
  result.error = 0;
  return result;
}

int counter_increment(struct counter_t counter)
{
  mutex_lock(counter.mutex_id);
  (*counter.counter)++;
  int result = *counter.counter;
  mutex_unlock(counter.mutex_id);  
  return result;
}


void counter_deattach(struct counter_t counter)
{
  shmdt((void*)counter.counter);
}

void counter_destroy(struct counter_t counter)
{
  shmctl(counter.shm_id, IPC_RMID, 0);
  mutex_destroy(counter.mutex_id);
}

